import { body, param, query } from 'express-validator';
import { validate } from '../validation';
import { QuestionType, QuestionDifficulty } from '../../types/question';

export const questionValidator = {
  create: validate([
    body('title')
      .isString()
      .trim()
      .isLength({ min: 3, max: 200 })
      .withMessage('Title must be between 3 and 200 characters'),
    body('content')
      .isString()
      .trim()
      .notEmpty()
      .withMessage('Content is required'),
    body('type')
      .isIn(Object.values(QuestionType))
      .withMessage(`Type must be one of: ${Object.values(QuestionType).join(', ')}`),
    body('difficulty')
      .isIn(Object.values(QuestionDifficulty))
      .withMessage(`Difficulty must be one of: ${Object.values(QuestionDifficulty).join(', ')}`),
    body('category')
      .isString()
      .trim()
      .notEmpty()
      .withMessage('Category is required'),
    body('options')
      .optional()
      .isArray()
      .custom((value, { req }) => {
        if (req.body.type === QuestionType.MULTIPLE_CHOICE && (!value || value.length < 2)) {
          throw new Error('Multiple choice questions must have at least 2 options');
        }
        return true;
      }),
    body('answer')
      .optional()
      .isString()
      .trim()
      .notEmpty()
      .withMessage('Answer cannot be empty when provided'),
    body('score')
      .optional()
      .isInt({ min: 0, max: 100 })
      .withMessage('Score must be between 0 and 100')
  ]),

  update: validate([
    param('id')
      .isInt({ min: 1 })
      .withMessage('Invalid question ID'),
    body('title')
      .optional()
      .isString()
      .trim()
      .isLength({ min: 3, max: 200 })
      .withMessage('Title must be between 3 and 200 characters'),
    body('content')
      .optional()
      .isString()
      .trim()
      .notEmpty()
      .withMessage('Content cannot be empty'),
    body('type')
      .optional()
      .isIn(Object.values(QuestionType))
      .withMessage(`Type must be one of: ${Object.values(QuestionType).join(', ')}`),
    body('difficulty')
      .optional()
      .isIn(Object.values(QuestionDifficulty))
      .withMessage(`Difficulty must be one of: ${Object.values(QuestionDifficulty).join(', ')}`),
    body('category')
      .optional()
      .isString()
      .trim()
      .notEmpty()
      .withMessage('Category cannot be empty'),
    body('options')
      .optional()
      .isArray()
      .custom((value, { req }) => {
        if (req.body.type === QuestionType.MULTIPLE_CHOICE && value && value.length < 2) {
          throw new Error('Multiple choice questions must have at least 2 options');
        }
        return true;
      }),
    body('answer')
      .optional()
      .isString()
      .trim()
      .notEmpty()
      .withMessage('Answer cannot be empty when provided'),
    body('score')
      .optional()
      .isInt({ min: 0, max: 100 })
      .withMessage('Score must be between 0 and 100')
  ]),

  getOne: validate([
    param('id')
      .isInt({ min: 1 })
      .withMessage('Invalid question ID')
  ]),

  delete: validate([
    param('id')
      .isInt({ min: 1 })
      .withMessage('Invalid question ID')
  ]),

  list: validate([
    query('page')
      .optional()
      .isInt({ min: 1 })
      .withMessage('Page must be a positive integer'),
    query('limit')
      .optional()
      .isInt({ min: 1, max: 100 })
      .withMessage('Limit must be between 1 and 100'),
    query('type')
      .optional()
      .isIn(Object.values(QuestionType))
      .withMessage(`Type must be one of: ${Object.values(QuestionType).join(', ')}`),
    query('difficulty')
      .optional()
      .isIn(Object.values(QuestionDifficulty))
      .withMessage(`Difficulty must be one of: ${Object.values(QuestionDifficulty).join(', ')}`),
    query('category')
      .optional()
      .isString()
      .trim()
      .notEmpty()
      .withMessage('Category cannot be empty')
  ])
};
